package cn.amaake.magicplugin.nacos.util.parse;

import cn.amaake.magicplugin.nacos.util.AbstractConfigParse;
import com.alibaba.nacos.api.config.ConfigType;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;

import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DefaultXmlConfigParse extends AbstractConfigParse {
    private DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    public DefaultXmlConfigParse() {
    }

    public Map<String, Object> parse(String configText) {
        Map<String, Object> properties = new LinkedHashMap(8);

        try {
            Document document = this.factory.newDocumentBuilder().parse(new ByteArrayInputStream(configText.getBytes("UTF-8")));
            Element root = document.getDocumentElement();
            Map<String, Object> map = new LinkedHashMap(8);
            this.recursionXmlToMap(map, root);
            this.mapToProperties("", properties, map);
            return properties;
        } catch (Exception var6) {
            Exception e = var6;
            throw new ConfigParseException(e);
        }
    }

    private void recursionXmlToMap(Map<String, Object> outMap, Element element) {
        NodeList nodeList = element.getChildNodes();
        String name = element.getNodeName();
        if (nodeList.getLength() == 1 && !nodeList.item(0).hasChildNodes()) {
            this.addData(outMap, name, element.getTextContent());
        } else {
            Map<String, Object> innerMap = new LinkedHashMap(1);
            int length = nodeList.getLength();

            for(int i = 0; i < length; ++i) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == 1) {
                    Element tElement = (Element)node;
                    this.recursionXmlToMap(innerMap, tElement);
                }
            }

            this.addData(outMap, name, innerMap);
        }

    }

    private void addData(Map<String, Object> map, String key, Object data) {
        if (map.containsKey(key)) {
            if (map.get(key) instanceof List) {
                ((List)map.get(key)).add(data);
            } else {
                List<Object> list = new LinkedList();
                list.add(map.get(key));
                map.put(key, list);
            }
        } else {
            map.put(key, data);
        }

    }

    private void mapToProperties(String prefixName, Map<String, Object> properties, Object data) {
        String tmpPrefix;
        if (data instanceof List) {
            List list = (List)data;

            for(int i = 0; i < list.size(); ++i) {
                int lastIndex = prefixName.lastIndexOf(46);
                tmpPrefix = prefixName.substring(0, lastIndex);
                prefixName.substring(lastIndex);
                this.mapToProperties(tmpPrefix + "[" + i + "]", properties, list.get(i));
            }
        } else if (data instanceof Map) {
            Map<String, Object> map = (Map)data;
            Iterator var10 = map.entrySet().iterator();

            while(var10.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry)var10.next();
                tmpPrefix = StringUtils.isEmpty(prefixName) ? (String)entry.getKey() : prefixName + "." + (String)entry.getKey();
                this.mapToProperties(tmpPrefix, properties, entry.getValue());
            }
        } else {
            properties.put(prefixName, String.valueOf(data));
        }

    }

    public String processType() {
        return ConfigType.XML.getType();
    }
}
